package com.bugsnag.ohos;

import java.util.AbstractQueue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * CallbackState
 *
 * @since 2021-07-02
 */
public class CallbackState implements CallbackAware {
    AbstractQueue<OnErrorCallback> onErrorTasks;
    AbstractQueue<OnBreadcrumbCallback> onBreadcrumbTasks;
    AbstractQueue<OnSessionCallback> onSessionTasks;

    /**
     * constructor
     */
    public CallbackState() {
        this(new ConcurrentLinkedQueue<>(),
            new ConcurrentLinkedQueue<>(), new ConcurrentLinkedQueue());
    }

    /**
     * constructor
     *
     * @param onErrorTasks
     * @param onBreadcrumbTasks
     * @param onSessionTasks
     */
    public CallbackState(AbstractQueue<OnErrorCallback> onErrorTasks,
                         AbstractQueue<OnBreadcrumbCallback> onBreadcrumbTasks,
                         AbstractQueue<OnSessionCallback> onSessionTasks) {
        this.onErrorTasks = onErrorTasks;
        this.onBreadcrumbTasks = onBreadcrumbTasks;
        this.onSessionTasks = onSessionTasks;
    }

    @Override
    public void addOnError(OnErrorCallback onError) {
        onErrorTasks.add(onError);
    }

    @Override
    public void removeOnError(OnErrorCallback onError) {
        onErrorTasks.remove(onError);
    }

    @Override
    public void addOnBreadcrumb(OnBreadcrumbCallback onBreadcrumb) {
        onBreadcrumbTasks.add(onBreadcrumb);
    }

    @Override
    public void removeOnBreadcrumb(OnBreadcrumbCallback onBreadcrumb) {
        onBreadcrumbTasks.remove(onBreadcrumb);
    }

    @Override
    public void addOnSession(OnSessionCallback onSession) {
        onSessionTasks.add(onSession);
    }

    @Override
    public void removeOnSession(OnSessionCallback onSession) {
        onSessionTasks.remove(onSession);
    }

    /**
     * runOnErrorTasks
     *
     * @param event
     * @param logger
     * @return boolean
     */
    public boolean runOnErrorTasks(Event event, Logger logger) {
        if (onErrorTasks.isEmpty()) {
            return true;
        }
        for (OnErrorCallback errorTask : onErrorTasks) {
            if (!errorTask.onError(event)) {
                return false;
            }
        }
        return true;
    }

    /**
     * runOnBreadcrumbTasks
     *
     * @param breadcrumb
     * @param logger
     * @return boolean
     */
    public boolean runOnBreadcrumbTasks(Breadcrumb breadcrumb, Logger logger) {
        if (onBreadcrumbTasks.isEmpty()) {
            return true;
        }
        for (OnBreadcrumbCallback breadcrumbTask : onBreadcrumbTasks) {
            if (!breadcrumbTask.onBreadcrumb(breadcrumb)) {
                return false;
            }
        }
        return true;
    }

    /**
     * runOnSessionTasks
     *
     * @param session
     * @param logger
     * @return boolean
     */
    public boolean runOnSessionTasks(Session session, Logger logger) {
        if (onSessionTasks.isEmpty()) {
            return true;
        }
        for (OnSessionCallback sessionTask : onSessionTasks) {
            if (!sessionTask.onSession(session)) {
                return false;
            }
        }
        return true;
    }

    /**
     * copy
     *
     * @return CallbackState
     */
    public CallbackState copy() {
        return new CallbackState(onErrorTasks, onBreadcrumbTasks, onSessionTasks);
    }
}
